home *** CD-ROM | disk | FTP | other *** search
- Program Transparent;
- { }
- { Example of How Transparency Works }
- { }
- { Programmed by David Dahl @ 1:272/38 }
- { }
- { This program is PUBLIC DOMAIN }
- { }
- Uses CRT, Palette;
-
- Type ImageArray = Array [0..15, 0..15] of Byte;
-
- LocationRec = Record
- X : Integer;
- Y : Integer;
- End;
-
- VGABufferArray = Array[0..199, 0..319] of Byte;
- VGABufferPtr = ^VGABufferArray;
-
- Const BobTemplate : ImageArray =
- ((00,00,00,00,00,00,07,07,07,07,00,00,00,00,00,00),
- (00,00,00,00,07,07,04,04,04,04,06,05,00,00,00,00),
- (00,00,00,07,04,04,04,04,04,04,04,04,04,00,00,00),
- (00,00,07,04,04,04,04,04,04,04,04,04,04,03,00,00),
- (00,07,04,04,04,04,04,04,04,04,04,04,04,04,02,00),
- (00,07,04,04,04,04,04,04,04,04,04,04,04,04,01,00),
- (07,04,04,04,04,04,04,04,04,04,04,04,04,04,04,01),
- (07,04,04,04,04,04,04,04,04,04,04,04,04,04,04,01),
- (07,04,04,04,04,04,04,04,04,04,04,04,04,04,04,01),
- (07,04,04,04,04,04,04,04,04,04,04,04,04,04,04,01),
- (00,06,04,04,04,04,04,04,04,04,04,04,04,04,01,00),
- (00,06,04,04,04,04,04,04,04,04,04,04,04,04,01,00),
- (00,00,05,04,04,04,04,04,04,04,04,04,04,01,00,00),
- (00,00,00,04,04,04,04,04,04,04,04,04,01,00,00,00),
- (00,00,00,00,03,02,04,04,04,04,01,01,00,00,00,00),
- (00,00,00,00,00,00,01,01,01,01,00,00,00,00,00,00));
-
- MaxBob = 2; { 3 Bobs (0 .. 2) }
-
- Var VGA : VGABufferPtr;
- BackGround : VGABufferPtr;
- WorkPage : VGABufferPtr;
-
- Pal : PaletteArray;
-
- BobImage : Array[0..MaxBob] of ImageArray;
- BobLocation : Array[0..MaxBob] of LocationRec;
-
- Counter1 : Integer;
- Counter2 : Integer;
-
- {-[ Set VGA Mode 13h (320 X 200 X 256 Chain 4) ]------------------------}
- Procedure SetMode13h; Assembler;
- ASM
- MOV AX, $13
- INT $10
- End;
- {-[ Put A 16 X 16 Image by ORing it With Background ]-------------------}
- Procedure Put16X16ImageOR (Var Bob : ImageArray;
- X, Y : Integer);
- Var CounterX,
- CounterY : Integer;
- Begin
- For CounterY := 0 to 15 do
- For CounterX := 0 to 15 do
- WorkPage^[CounterY + Y, CounterX + X] :=
- WorkPage^[CounterY + Y, CounterX + X] OR Bob[CounterX, CounterY];
- End;
- {-[ Update Bob Positions ]----------------------------------------------}
- Procedure UpdateBobs;
- Var BobCounter : Integer;
- Begin
- For BobCounter := 0 to MaxBob do
- Begin
- Inc (Counter1, 1);
- While (Counter1 >= 360) do
- Dec(Counter1, 360);
-
- If (Counter1 MOD 2) = 0
- Then
- Begin
- Inc(Counter2,1);
- While (Counter2 >= 360) do
- Dec(Counter2, 360);
- End;
-
- BobLocation[BobCounter].X := 160 +
- Round(90 * -Sin((Counter1 + (BobCounter*Counter2))*PI/180));
-
- BobLocation[BobCounter].Y := 95 +
- Round(60 * Cos((Counter2 + (BobCounter*Counter1))*PI/180));
-
- End;
- End;
- {-[ Draw All Bobs To Work Buffer ]--------------------------------------}
- Procedure DrawBobs;
- Var BobCounter : Integer;
- Begin
- For BobCounter := 0 to MaxBob do
- Put16X16ImageOR (BobImage[BobCounter],
- BobLocation[BobCounter].X, BobLocation[BobCounter].Y);
- End;
- {-[ Initialize Variables ]----------------------------------------------}
- Procedure InitializeVariables;
- Const Tbl : Array [0..MaxBob] of Byte = (8, 16, 32);
- Var BobCounter : Integer;
- CX, CY : Integer;
- Begin
- { Make Individual Bobs From Template }
- For BobCounter := 0 to MaxBob do
- Begin
- BobImage[BobCounter] := BobTemplate;
-
- For CY := 0 to 15 do
- For CX := 0 to 15 do
- If BobImage[BobCounter][CX,CY] <> 0
- Then
- BobImage[BobCounter][CX,CY] :=
- BobImage[BobCounter][CX,CY] OR Tbl[BobCounter];
- End;
-
- Counter1 := 0;
- Counter2 := 0;
- End;
- {-[ Build Palette ]-----------------------------------------------------}
- Procedure BuildPalette;
- Var ColorCounter : Integer;
- Begin
- { Initialize Palette Buffer To All Black }
- FillChar (Pal, SizeOf(Pal), 0);
-
- For ColorCounter := 0 to 7 do
- Begin
- { Make Red, Green, and Blue Bobs }
- Pal[ColorCounter OR 08].Red := 21 + (ColorCounter * 6);
- Pal[ColorCounter OR 16].Green := 21 + (ColorCounter * 6);
- Pal[ColorCounter OR 32].Blue := 21 + (ColorCounter * 6);
-
- { Make Colors Where Red and Green Bobs Overlap }
- Pal[ColorCounter OR 08 OR 16].Red := 21 + (ColorCounter * 6);
- Pal[ColorCounter OR 08 OR 16].Green := 21 + (ColorCounter * 6);
-
- { Make Colors Where Red and Blue Bobs Overlap }
- Pal[ColorCounter OR 08 OR 32].Red := 21 + (ColorCounter * 6);
- Pal[ColorCounter OR 08 OR 32].Blue := 21 + (ColorCounter * 6);
-
- { Make Colors Where Green and Blue Bobs Overlap }
- Pal[ColorCounter OR 16 OR 32].Green := 21 + (ColorCounter * 6);
- Pal[ColorCounter OR 16 OR 32].Blue := 21 + (ColorCounter * 6);
-
- { Make Colors Where Red, Green and Blue Bobs Overlap }
- Pal[ColorCounter OR 08 OR 16 OR 32].Red := 21+(ColorCounter * 6);
- Pal[ColorCounter OR 08 OR 16 OR 32].Green := 21+(ColorCounter * 6);
- Pal[ColorCounter OR 08 OR 16 OR 32].blue := 21+(ColorCounter * 6);
- End;
-
- { Make Colors Where The Grey Square Overlaps The Bobs }
- For ColorCounter := 128 to 255 do
- Begin
- Pal[ColorCounter].Red := (Pal[ColorCounter-128].Red DIV 4)+14;
- Pal[ColorCounter].Green := (Pal[ColorCounter-128].Green DIV 4)+14;
- Pal[ColorCounter].Blue := (Pal[ColorCounter-128].Blue DIV 4)+14;
- End;
- End;
- {-[ Draw Grey Square In Background Buffer ]-----------------------------}
- Procedure BuildBackground;
- Var Y, X : Integer;
- Begin
- FillChar (BackGround^, SizeOf(BackGround^), 0);
-
- For Y := 50 to 150 do
- For X := 100 to 220 do
- BackGround^[Y, X] := 128;
-
- End;
- {=[ Main Program ]======================================================}
- Begin
- VGA := Ptr ($A000,$0000);
- New (WorkPage);
- New (BackGround);
-
- InitializeVariables;
- BuildPalette;
- BuildBackground;
-
- SetMode13h;
- SetPalette (Pal);
-
- Repeat
- UpdateBobs; { Update Bob Positions }
- WorkPage^ := BackGround^; { Clear WorkPage With Static Image }
- DrawBobs; { Draw Bobs }
-
- { Wait For Retrace }
- Repeat Until ((Port[$3DA] AND 8) <> 0);
-
- VGA^ := WorkPage^; { Display Page }
- Until KeyPressed;
-
- TextMode (C80);
-
- Dispose (BackGround);
- Dispose (WorkPage);
- End.
-
- { PALETTE CODE FOLLOWS }
-
- {
- TD> I've seen it done in many places, but I haven't seen any info on
- TD> how it's done: What is the basic algorithm for fading from one
- TD> palette to another.
-
- Many people do palette fading incorrectly. The correct
- way to do it would be to set up a relation such as:
-
- Palette_Element Calculated_Element
- --------------- = ------------------
- Max_Intensity Current_Intensity
-
- Where Palette_Element is a single element in our master DAC
- table, Max_Intensity is the maximum allowable intensity level for
- our scale, Current_Intensity is a number between 0 and
- Max_Intensity which represents the level we want, and
- Calculated_Element is the new value for the element of our DAC
- table. But since we want the Calculated_Element, we re-write it
- as this equation:
-
- Calculated_Element = Palette_Element * Current_Intensity
- -----------------------------------
- Max_Intensity
-
- The above equation will allow us to fade a given palette set to
- black or from black to a given palette set. To fade out an entire
- palette set, you would need to calculate the above for the red,
- green, and blue components of each color in the 256 element DAC
- table.
- Fading from one palette set to another palette set is
- very similar. What you must do is fade one palette set to black
- while simultaneously fade from black to another palette set and
- add the two values. The equation for this is:
-
- CE = ((PE1 * (MI - CI)) + (PE2 * CI)) / MI
-
- Where CE is the calculated element, PE1 and PE2 are corresponding
- palette elements from palette 1 and 2, MI is the maximum
- intensity in our scale, and CI is the current intensity we want
- (num between 0 and MI). }
-
- Unit Palette;
- { Programmed By David Dahl @ FidoNet 1:272/38 }
- (* PUBLIC DOMAIN *)
- Interface
- Type PaletteRec = Record
- Red : Byte;
- Green : Byte;
- Blue : Byte;
- End;
- PaletteArray = Array [0..255] of PaletteRec;
-
- Procedure SetPalette (Var PaletteIn : PaletteArray);
- Procedure FadeFromPaletteToBlack (Var PaletteIn : PaletteArray);
- Procedure FadeFromBlackToPalette (Var PaletteIn : PaletteArray);
- Procedure FadeFromPalette1ToPalette2 (Var Palette1 : PaletteArray;
- Var Palette2 : PaletteArray);
- Implementation
- Procedure SetPalette (Var PaletteIn : PaletteArray); Assembler;
- Asm
- { Get Address of PaletteIn }
- LDS SI, PaletteIn
- CLD
-
- { Tell VGA To Start With First Palette Element }
- XOR AX, AX
- MOV DX, $3C8
- OUT DX, AL
-
- { Wait For Retrace }
- MOV DX, $3DA
- @VRWait1:
- IN AL, DX
- AND AL, 8
- JZ @VRWait1
-
- { Set First Half Of Palette }
- MOV DX, $3C9
- MOV CX, 128 * 3
- @PALLOOP1:
- LODSB { DON'T use "REP OUTSB" since some VGA cards can't handle it }
- OUT DX, AL
- LOOP @PALLOOP1
-
- { Wait For Retrace }
- PUSH DX
- MOV DX, $3DA
- @VRWait2:
- IN AL, DX
- AND AL, 8
- JZ @VRWait2
- POP DX
-
- { Set Last Half Of Palette }
- MOV CX, 128 * 3
- @PALLOOP2:
- LODSB
- OUT DX, AL
- LOOP @PALLOOP2
- End;
-
- Procedure FadeFromPaletteToBlack (Var PaletteIn : PaletteArray);
- Var WorkPalette : PaletteArray;
- Counter : Integer;
- Intensity : Integer;
- Begin
- For Intensity := 31 downto 0 do
- Begin
- For Counter := 0 to 255 do
- Begin
- WorkPalette[Counter].Red :=
- (PaletteIn[Counter].Red * Intensity) DIV 32;
- WorkPalette[Counter].Green :=
- (PaletteIn[Counter].Green * Intensity) DIV 32;
- WorkPalette[Counter].Blue :=
- (PaletteIn[Counter].Blue * Intensity) DIV 32;
- End;
- SetPalette (WorkPalette);
- End;
- End;
-
- Procedure FadeFromBlackToPalette (Var PaletteIn : PaletteArray);
- Var WorkPalette : PaletteArray;
- Counter : Integer;
- Intensity : Integer;
- Begin
- For Intensity := 1 to 32 do
- Begin
- For Counter := 0 to 255 do
- Begin
- WorkPalette[Counter].Red :=
- (PaletteIn[Counter].Red * Intensity) DIV 32;
- WorkPalette[Counter].Green :=
- (PaletteIn[Counter].Green * Intensity) DIV 32;
- WorkPalette[Counter].Blue :=
- (PaletteIn[Counter].Blue * Intensity) DIV 32;
- End;
- SetPalette (WorkPalette);
- End;
- End;
-
- Procedure FadeFromPalette1ToPalette2 (Var Palette1 : PaletteArray;
- Var Palette2 : PaletteArray);
- Var WorkPalette : PaletteArray;
- Counter : Integer;
- CrossFade : Integer;
- Begin
- For CrossFade := 0 to 32 do
- Begin
- For Counter := 0 to 255 do
- Begin
- WorkPalette[Counter].Red :=
- ((Palette1[Counter].Red * (32 - CrossFade)) +
- (Palette2[Counter].Red * CrossFade)) DIV 32;
- WorkPalette[Counter].Green :=
- ((Palette1[Counter].Green * (32 - CrossFade)) +
- (Palette2[Counter].Green * CrossFade)) DIV 32;
- WorkPalette[Counter].Blue :=
- ((Palette1[Counter].Blue * (32 - CrossFade)) +
- (Palette2[Counter].Blue * CrossFade)) DIV 32;
- End;
- SetPalette (WorkPalette);
- End;
- End;
- End.
-
- TUTORIAL !!
-
- Transparent objects are rather simple. What you do is
- set up your palette so pure colors are represented by powers of
- two. This way you can "mix" your colors by ORing the values
- together. For simplicity's sake, this example will use 3 colors:
-
- Bit 7 6 5 4 3 2 1 0
- | | |
- | | +----> Red
- | +------> Green
- +--------> Blue
-
- So now you would set your palette up as follows:
-
- All single colors:
-
- 2^0 = 1 -- Red
- 2^1 = 2 -- Green
- 2^2 = 4 -- Blue
-
- All possible 2 color mixes:
-
- 2^0 OR 2^1 = 1 OR 2 = 3 -- Red + Green = Yellow
- 2^0 OR 2^2 = 1 OR 4 = 5 -- Red + Blue = Magenta
- 2^1 OR 2^2 = 2 OR 4 = 6 -- Green + Blue = Cyan
-
- All possible 3 color mixes:
-
- 2^0 OR 2^1 OR 2^2 = 1 OR 2 OR 4 = 7 -- R + G + B = White
-
- So our palette is set up as:
-
- 0 - Black
- 1 - Red
- 2 - Green
- 3 - Yellow
- 4 - Blue
- 5 - Magenta
- 6 - Cyan
- 7 - White
-
- Now let's say we have a Red, Green, and a Blue square. The
- bitmap of the red square will be made up of bytes of the value 1,
- the green square will be made up of the value 2, and the blue
- square will be made up of the value 4 as so:
-
- Red Green Blue
-
- 11111111 22222222 44444444
- 11111111 22222222 44444444
- 11111111 22222222 44444444
- 11111111 22222222 44444444
-
- To put the squares, you just have to OR put them to your frame
- buffer. If they overlap, they will automatically mix as so:
-
- The 3 overlaping bitmaps The 3 overlaping bitmaps
- in frame buffer using an in frame buffer showing
- OR'd image put: what colors are where:
-
- 11111111 RRRRRRRR
- 11111111 RRRRRRRR
- 111133332222 RRRRYYYYGGGG
- 155577776222 RMMMWWWWCGGG
- 44466666222 BBBCCCCCGGG
- 44466666222 BBBCCCCCGGG
- 44444444 BBBBBBBB
-
- The following example program uses this bit scheme:
-
- Bit 7 6 5 4 3 2 1 0
- | | | | +-+-+---> Color Intensity (0:Least - 7:Full)
- | | | +---------> Red
- | | +-----------> Green
- | +-------------> Blue
- +-----------------> Grey
-
-
- David Dahl